package com.puzzlebazar.client.main.view;

import java.util.Iterator;

import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.puzzlebazar.client.util.AutoHyperlink;
import com.puzzlebazar.client.util.TokenFactory;

public class TabbedView extends Composite implements UpdateTokenCallback {

	private final VerticalPanel mainPanel = new VerticalPanel();
	private final HorizontalPanel tabBarHolder = new HorizontalPanel();
	private final HorizontalPanel tabBar = new HorizontalPanel();
	private final VerticalPanel mainArea = new VerticalPanel();
	
	private int selectedTab = -1;
	
	public TabbedView() {

		tabBar.setStylePrimaryName( "tabbedViewTabBar" );

		tabBarHolder.setStylePrimaryName( "tabbedViewTabBarHolder" );
		tabBarHolder.setWidth( "100%" );
		tabBarHolder.add( tabBar );

		mainArea.setStylePrimaryName( "tabbedViewMain" );
		mainArea.setWidth( "100%" );
		mainArea.add( new HTML("&nbsp;") );
		
		mainPanel.setWidth( "100%" );		
		mainPanel.add( tabBarHolder );
		mainPanel.add( mainArea );

		initWidget( mainPanel );
	}		
	
	/**
	 * Sets the main widget of the view, the one that will be displayed in the large panel
	 * 
	 * @param widget The widget to use as a main widget
	 */
	public void setMainWidget(Widget widget ) {
		mainArea.clear();
		mainArea.add(widget);
	}			

	/**
	 * Adds a new tab to this tabbed view
	 * 
	 * @param tabName The name to use for this tab
	 * @param tokenFactory The factory to use to create associated token
	 * @return the index of the newly created tab
	 */
	public int addTab( String tabName, TokenFactory tokenFactory ) {
		AutoHyperlink tab  = new AutoHyperlink(tabName, tokenFactory );
		tab.setStylePrimaryName( "tabbedViewTab" );
		tabBar.add( tab );
		return tabBar.getWidgetCount() - 1;
	}	
	
	/**
	 * Selects a give tab, currently selected tab will be deselected. Does not call the 
	 * hyperlink associated with the tab.
	 * 
	 * @param tabNumber The index of the tab to select, the first tab has index 0 (-1 to unselect all)
	 */
	public void selectTab( int tabNumber ) {

		if( selectedTab >= 0 && selectedTab < tabBar.getWidgetCount() )
			tabBar.getWidget( selectedTab ).removeStyleDependentName( "selected" );		
		selectedTab = -1;
		
		if( tabNumber < 0 || tabNumber >= tabBar.getWidgetCount() )
			return;

		selectedTab = tabNumber;
		tabBar.getWidget( selectedTab ).addStyleDependentName( "selected" );				
	}

	/**
	 * Change the visibility status of the specified tab. If the tab is currently selected and is
	 * hidden, the view will not change!
	 * 
	 * @param tabNumber The number of the tab to change visibility
	 * @param visible True to make the tab visible, false to hide it
	 */
	public void setTabVisible(int tabNumber, boolean visible) {
		assert( tabNumber >= 0 && tabNumber < tabBar.getWidgetCount() );
		tabBar.getWidget( tabNumber ).setVisible( visible );
	}
	
	@Override
	public void updateTokens() {
		
		for (Iterator<Widget> iterator = tabBar.iterator(); iterator.hasNext();) {
			AutoHyperlink link = (AutoHyperlink)iterator.next();
			link.updateTokens();
		}
	
		Widget mainWidget = mainArea.getWidget(0);
		if( mainWidget != null && mainWidget instanceof UpdateTokenCallback )
			((UpdateTokenCallback)mainWidget).updateTokens();

	}

	
}
